//
//  TokenView.m
//  TabulaImaginarius2
//
//  Created by TA2 on 5/23/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "TokenView.h"
#import "NetworkController.h"

@implementation TokenView

@synthesize map;
@synthesize scale;
@synthesize tileSize;
@synthesize currentPoint;
@synthesize addTokensIsActivated;
@synthesize addObjectsIsActivated;
@synthesize protocolId;

+ (Class)layerClass {
	return [CATiledLayer class];
}

- (id)initWithMap:(Map *)newMap withTileSize:(CGSize)size withScale:(int)scale{
    if ((self = [super initWithFrame:CGRectMake(0, 0, newMap.size.width, newMap.size.height)])) {
        self.map = newMap;
        CATiledLayer *tiledLayer = (TiledLayer *)[self layer];
		tiledLayer.tileSize = size;
		tiledLayer.levelsOfDetail = 3;
		tiledLayer.levelsOfDetailBias = 2;
		if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { 
			tiledLayer.levelsOfDetail = 3;
			tiledLayer.levelsOfDetailBias = 2;
		}
		self.scale = scale;
		tileSize = (CGSize){tiledLayer.tileSize.width/self.scale, tiledLayer.tileSize.height/self.scale};
    }
	self.backgroundColor = [UIColor clearColor];
    return self;	
}

- (void)dealloc {
    [map release];
    map = nil;
    
    [protocolId release];
    protocolId = nil;
    [super dealloc];
}

- (void)drawRect:(CGRect)rect {
	// calculate the rows and columns of tiles that intersect the rect we have been asked to draw
	int firstCol = floorf(CGRectGetMinX(rect) / tileSize.width);
	int lastCol = floorf((CGRectGetMaxX(rect)-1) / tileSize.width);
	int firstRow = floorf(CGRectGetMinY(rect) / tileSize.height);
	int lastRow = floorf((CGRectGetMaxY(rect)-1) / tileSize.height);
	
	for (int row = firstRow; row <= lastRow; row++) {
		for (int col = firstCol; col <= lastCol; col++) {
			NSArray *tiles = [map graphicsLayersForTokenAtPoint:CGPointMake(col, row) withViewId:protocolId];
			for (NSObject *tileObject in tiles) {
				CGRect tileRect = CGRectMake(tileSize.width * col, tileSize.height * row,
											 tileSize.width, tileSize.height);
				tileRect = CGRectIntersection(self.bounds, tileRect);
				CGContextDrawLayerInRect(UIGraphicsGetCurrentContext(), tileRect, (CGLayerRef)tileObject);
			}
			CGLayerRef movingTile = [map graphicsLayerForMovingTokenAtPoint:CGPointMake(col, row) withViewId:protocolId];
			if (movingTile) {
				CGRect tileRect = CGRectMake(tileSize.width * col, tileSize.height * row,
											 tileSize.width, tileSize.height);
				tileRect = CGRectIntersection(self.bounds, tileRect);
				//CGRect tileRect = CGRectMake([map.currentlyMovingToken getOrigin].x * tileSize.width, [map.currentlyMovingToken getOrigin].y * tileSize.height, tileSize.width, tileSize.height);
				//tileRect = CGRectIntersection(self.bounds, tileRect);
				CGContextDrawLayerInRect(UIGraphicsGetCurrentContext(), tileRect, movingTile);
			}
		}
	}
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
	UITouch *touch = [touches anyObject];
	lastPoint = [touch locationInView:self];
	CGPoint gridCoords = [self convertCoordsToGridCoords:CGPointMake(lastPoint.x, lastPoint.y)];
	Token *token = [map tokenForPoint:gridCoords withViewId:protocolId];
	if (token) {
        @synchronized (map.currentlyMovingTokenLock) {
            if ([LoadedImages sharedLoadedImages].eraserActivated && (addTokensIsActivated || addObjectsIsActivated)) {
                NSMutableArray *points = [token getPointsWithOffset:0];
                for (NSValue *pointValue in points) {
                    CGPoint point = [pointValue CGPointValue];
                    [map removeToken:token fromPoint:point];
                    [self setNeedsDisplayInRect:(CGRect){(CGPoint){point.x * tileSize.width, point.y * tileSize.height}, (CGSize){tileSize.width, tileSize.height}}];
                    [(TokenProtocol *)[[NetworkController sharedNetworkController].networkProtocols objectForKey:([NSString stringWithString:protocolId])] deleteToken:token.tokenId];
                }
            } else if (![Players sharedLocalPlayer].currentlyMovingToken) {
                while (token.retainCount < 2) {
                    [token retain];
                }
                [token enterMovingMode:[self convertCoordsToGridCoords:lastPoint]];
                originalTokenPoint = lastPoint;
                NSMutableArray *points = [token getPointsWithOffset:0];
                for (NSValue *pointValue in points) {
                    CGPoint point = [pointValue CGPointValue];
                    [map removeToken:token fromPoint:point];
                    [self setNeedsDisplayInRect:(CGRect){(CGPoint){point.x * tileSize.width, point.y * tileSize.height}, (CGSize){tileSize.width, tileSize.height}}];
                }
                [Players sharedLocalPlayer].currentlyMovingToken = token;
                [(TokenProtocol *)[[NetworkController sharedNetworkController].networkProtocols objectForKey:([NSString stringWithString:protocolId])] startMovingToken:gridCoords withId:token.tokenId];
            }
		} 
	} 
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
	@synchronized (map.currentlyMovingTokenLock) {
		if ([Players sharedLocalPlayer].currentlyMovingToken) {
			if ([touches count] > 1) {
				Token *token = [Players sharedLocalPlayer].currentlyMovingToken;
				[Players sharedLocalPlayer].currentlyMovingToken = nil;
				NSMutableArray *points = [token getPointsWithOffset:1];
				for (NSValue *pointValue in points) {
					CGPoint point = [pointValue CGPointValue];
					[self setNeedsDisplayInRect:(CGRect){(CGPoint){point.x * tileSize.width, point.y * tileSize.height}, (CGSize){tileSize.width, tileSize.height}}];
				}
				CGPoint gridCoords = [self convertCoordsToGridCoords:CGPointMake(originalTokenPoint.x, originalTokenPoint.y)];
				[token setOrigin:gridCoords];
				points = [token getPointsWithOffset:0];
				for (NSValue *pointValue in points) {
					CGPoint point = [pointValue CGPointValue];
					[map addToken:token atPoint:point withTileSize:tileSize];
					[self setNeedsDisplayInRect:(CGRect){(CGPoint){point.x * tileSize.width, point.y * tileSize.height}, (CGSize){tileSize.width, tileSize.height}}];
				}
                [(TokenProtocol *)[[NetworkController sharedNetworkController].networkProtocols objectForKey:([NSString stringWithString:protocolId])] placeMovingToken:gridCoords];
			} else {
				currentPoint = [[touches anyObject] locationInView:self];
				CGPoint gridCoords = [self convertCoordsToGridCoords:currentPoint];
				if (!CGPointEqualToPoint([[Players sharedLocalPlayer].currentlyMovingToken getOrigin], gridCoords)) {
					NSMutableArray *points = [[Players sharedLocalPlayer].currentlyMovingToken getPointsWithOffset:0];
					for (NSValue *pointValue in points) {
						CGPoint point = [pointValue CGPointValue];
						[self setNeedsDisplayInRect:(CGRect){(CGPoint){point.x * tileSize.width, point.y * tileSize.height}, (CGSize){tileSize.width, tileSize.height}}];
					}
					[[Players sharedLocalPlayer].currentlyMovingToken setOrigin:gridCoords];
					points = [[Players sharedLocalPlayer].currentlyMovingToken getPointsWithOffset:0];
					for (NSValue *pointValue in points) {
						CGPoint point = [pointValue CGPointValue];
						[self setNeedsDisplayInRect:(CGRect){(CGPoint){point.x * tileSize.width, point.y * tileSize.height}, (CGSize){tileSize.width, tileSize.height}}];
					}
					[(TokenProtocol *)[[NetworkController sharedNetworkController].networkProtocols objectForKey:([NSString stringWithString:protocolId])] moveMovingToken:gridCoords];
				}
			}
		}
	}
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
	UITouch *touch = [touches anyObject];
	currentPoint = [touch locationInView:self];
	CGPoint gridCoords = [self convertCoordsToGridCoords:CGPointMake(currentPoint.x, currentPoint.y)];
	@synchronized (map.currentlyMovingTokenLock) {
        if ([Players sharedLocalPlayer].currentlyMovingToken && ![LoadedImages sharedLoadedImages].drawingActivated) {
			Token *token = [Players sharedLocalPlayer].currentlyMovingToken;
			[Players sharedLocalPlayer].currentlyMovingToken = nil;
			NSMutableArray *points = [token getPointsWithOffset:1];
			for (NSValue *pointValue in points) {
				CGPoint point = [pointValue CGPointValue];
				[self setNeedsDisplayInRect:(CGRect){(CGPoint){point.x*tileSize.width, point.y*tileSize.height}, (CGSize){tileSize.width, tileSize.height}}];
			}
			[token setOrigin:gridCoords];
			points = [token getPointsWithOffset:0];
			for (NSValue *pointValue in points) {
				CGPoint point = [pointValue CGPointValue];
				[map addToken:token atPoint:point withTileSize:tileSize];
				[self setNeedsDisplayInRect:(CGRect){(CGPoint){point.x*tileSize.width, point.y*tileSize.height}, (CGSize){tileSize.width, tileSize.height}}];
			}
			[token leaveMovingMode];
			[(TokenProtocol *)[[NetworkController sharedNetworkController].networkProtocols objectForKey:([NSString stringWithString:protocolId])] placeMovingToken:gridCoords];
		} else if (addTokensIsActivated && ![LoadedImages sharedLoadedImages].eraserActivated) {
			NSString *path = [LoadedImages sharedLoadedImages].selectedTokenImage;
			if (path) {
				UIImage *image = [[LoadedImages sharedLoadedImages].images objectForKey:path];
				NSArray *tiledImages = [[LoadedImages sharedLoadedImages].tiledTokenImages objectForKey:path];
				if (!tiledImages) {
					NSArray *arguments = [path componentsSeparatedByCharactersInSet:
                                          [NSCharacterSet characterSetWithCharactersInString:@"_"]];
					tiledImages = [Token tileImage:image withWidth:[[arguments objectAtIndex:[arguments count] -1] intValue] withHeight:[[[arguments objectAtIndex:[arguments count] -2] stringByDeletingPathExtension] intValue]];
					[[LoadedImages sharedLoadedImages].tiledTokenImages setObject:tiledImages forKey:path];
				}
				NSString *tempId = [NSString stringWithString:[[[[Players sharedLocalPlayer].ip stringByAppendingString:@"§"] stringByAppendingString:protocolId]stringByAppendingString:[NSString stringWithFormat:@"§%d", [map getNextId:protocolId]]]];
				Token *newToken = [[[Token alloc] initWithImageArray:tiledImages withId:tempId] autorelease];
                newToken.protocolId = protocolId;
				newToken.tokenImagePath = path;
				[newToken setOrigin:gridCoords];
				[(TokenProtocol *)[[NetworkController sharedNetworkController].networkProtocols objectForKey:([NSString stringWithString:protocolId])] sendToken:path atPoint:gridCoords withId:newToken.tokenId];
				NSMutableArray *points = [newToken getPointsWithOffset:0];
				for (NSValue *pointValue in points) {
					CGPoint point = [pointValue CGPointValue];
					[map addToken:newToken atPoint:point withTileSize:tileSize];
					[self setNeedsDisplayInRect:(CGRect){(CGPoint){point.x*tileSize.width, point.y*tileSize.height}, (CGSize){tileSize.width, tileSize.height}}];
				}
			} 
		} else if (addObjectsIsActivated && ![LoadedImages sharedLoadedImages].eraserActivated) {
            NSString *path = [LoadedImages sharedLoadedImages].selectedObjectImage;
            if (path) {
                UIImage *image = [[LoadedImages sharedLoadedImages].images objectForKey:path];
                NSArray *tiledImages = [[LoadedImages sharedLoadedImages].tiledTokenImages objectForKey:path];
                if (!tiledImages) {
                    NSArray *arguments = [path componentsSeparatedByCharactersInSet:
                                          [NSCharacterSet characterSetWithCharactersInString:@"_"]];
                    tiledImages = [Token tileImage:image withWidth:[[arguments objectAtIndex:[arguments count] -1] intValue] withHeight:[[[arguments objectAtIndex:[arguments count] -2] stringByDeletingPathExtension] intValue]];
                    [[LoadedImages sharedLoadedImages].tiledTokenImages setObject:tiledImages forKey:path];
                }
                NSString *tempId = [NSString stringWithString:[[[[Players sharedLocalPlayer].ip stringByAppendingString:@"§"] stringByAppendingString:protocolId]stringByAppendingString:[NSString stringWithFormat:@"§%d", [map getNextId:protocolId]]]];
                Token *newToken = [[[Token alloc] initWithImageArray:tiledImages withId:tempId] autorelease];
                newToken.protocolId = protocolId;
                newToken.tokenImagePath = path;
                [newToken setOrigin:gridCoords];
                [(TokenProtocol *)[[NetworkController sharedNetworkController].networkProtocols objectForKey:([NSString stringWithString:protocolId])] sendToken:path atPoint:gridCoords withId:newToken.tokenId];
                NSMutableArray *points = [newToken getPointsWithOffset:0];
                for (NSValue *pointValue in points) {
                    CGPoint point = [pointValue CGPointValue];
                    [map addToken:newToken atPoint:point withTileSize:tileSize];
                    [self setNeedsDisplayInRect:(CGRect){(CGPoint){point.x*tileSize.width, point.y*tileSize.height}, (CGSize){tileSize.width, tileSize.height}}];
                }
            }
        }
	}
}

- (CGPoint)convertCoordsToGridCoords:(CGPoint)coords {
	uint x;
	uint y;
	x = (uint)coords.x / (uint)tileSize.width;
	y = (uint)coords.y / (uint)tileSize.height;
	return (CGPoint){x, y};
}

@end
